#include <iostream>
#include <ctime>

// #define DEBUG_LEVEL 0
// #define INFO_LEVEL 1
// #define WARING_LEVEL 2 
// #define ERROR_LEVEL 3
// #define FATAL_LEVEL 4

enum { 
    DEBUG,
    INFO, 
    WARNING,
    ERROR, 
    FATAL
};

class Logger
{
public:
    static Logger& instance()
    {
        static Logger logger;
        return logger;
    }
    std::ostream &log(const std::string &level_str, const std::string &file_name, int line)
    {       
        time_t _timer = time(nullptr);
        struct tm *ptm = localtime(&_timer);
        char time_buf[32] = {0};
        std::string time_str;
        strftime(time_buf, 31, "%H:%M:%S", ptm);
        std::string message = "[" + std::string(std::move(time_buf)) + "]";

        message += "[" + level_str + "]";                                   // 添加日志等级
        message += "[" + file_name + ":" + std::to_string(line) + "] "; // 错误定位

        std::cout << message; // 利用cout缓冲区刷新规则（不换行不刷新）
        return std::cout;
    }
};

#define LOG(level) Logger::instance().log(#level, __FILE__, __LINE__)
#define LOG_DEBUG LOG(DEBUG)
#define LOG_INFO LOG(INFO)
#define LOG_WARNING LOG(WARNING)
#define LOG_ERROR LOG(ERROR)
#define LOG_FATAL LOG(FATAL)

int main()
{
    // time_t _timer = time(nullptr);
    // struct tm* ptm = localtime(&_timer);
    // std::cout << ptm->tm_hour << ":" << ptm->tm_min << ":" << ptm->tm_sec << '\n';

    LOG_DEBUG << "this is a DEBUG log!\n";
    LOG_INFO << "this is a INFO log!\n";
    LOG_WARNING << "this is a WARING log!\n";
    LOG_ERROR << "this is a ERROR log!\n";
    LOG_FATAL << "this is a FATAL log!\n";
    return 0;
}